package cn.hejiang.mamis.access.controller;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.hejiang.mamis.access.properties.OidcProperties;
import cn.hejiang.mamis.core.constant.Constants;
import cn.hejiang.mamis.core.dto.ResultDTO;
import cn.hejiang.mamis.core.entity.PlatUser;
import cn.hejiang.mamis.core.entity.SessionDetails;
import cn.hejiang.mamis.core.service.PlatUserService;
import cn.hejiang.mamis.core.service.ContextService;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("/mamis/access")
@Slf4j
public class LoginController {
	@Autowired
	OidcProperties oidcProps;

	@Autowired
	private PlatUserService platUserService;

	@Autowired
	private ContextService sessionService;

	@Value("${web.proxy.context-path:}")
	String webProxyContextPath;
	
	private String getContextPath(HttpServletRequest request) {
		if (StrUtil.isNotBlank(webProxyContextPath)) {
			String ctx = webProxyContextPath.trim();
			return ctx.endsWith("/") ? ctx.substring(0, ctx.length() - 1) : ctx;
		}
		
		return request.getContextPath();
	}

	@GetMapping("/login")
	public String login(HttpServletRequest request, HttpServletResponse response, Model model,
			@RequestParam(name = "redirect", required = false) String redirect) {
		// 支持 oidc 登录
		if (oidcProps.isEnabled()) {
			try {
				request.getRequestDispatcher("/mamis/access/oidc/login").forward(request, response);
			} catch (ServletException | IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}

		// 默认登录页面
		model.addAttribute("js", "/amis/pages/plat-login.js");

		model.addAttribute("contextPath", getContextPath(request));

		return "page";
	}

	@GetMapping("/captcha.png")
	public void captcha(HttpServletRequest request, HttpServletResponse response) {
		final HttpSession session = request.getSession();

		AbstractCaptcha captcha = CaptchaUtil.createShearCaptcha(150, 37, 4, 3);
		String code = captcha.getCode();
		session.setAttribute(Constants.CAPTCHA_CODE, code);
		session.setAttribute(Constants.CAPTCHA_TIMEOUT, System.currentTimeMillis() + 5 * 60 * 1000);
		try {
			captcha.write(response.getOutputStream());
			response.getOutputStream().close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@PostMapping(path = "/login", consumes = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	public ResultDTO login(HttpServletRequest request, HttpServletResponse response,
			@RequestBody Map<String, String> data) {
		final HttpSession session = request.getSession();

		String captchaCode = (String) session.getAttribute(Constants.CAPTCHA_CODE);
		Long captchaTimeout = (Long) session.getAttribute(Constants.CAPTCHA_TIMEOUT);

		final String username = data.get("username");
		final String password = data.get("password");
		final String captcha = data.get("captcha");

		if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
			return ResultDTO.error("用户名/密码不能为空");
		}

		if (StringUtils.isBlank(captcha)) {
			return ResultDTO.error("验证码不能为空");
		}

		if (StringUtils.isBlank(captchaCode) || captchaTimeout == null || captchaTimeout < System.currentTimeMillis()
				|| !captchaCode.equalsIgnoreCase(captcha)) {
			return ResultDTO.error("验证码错误");
		}

		PlatUser user = platUserService.getUserByLoginName(username);
		if (user == null) {
			return ResultDTO.error("用户名/密码错误");
		}

		if (!user.getPassword().equals(SecureUtil.md5(password + user.getSalt()))) {
			return ResultDTO.error("用户名/密码错误");
		}

		if (user.getStatus() != 1) {
			return ResultDTO.error("已禁止当前用户登录");
		}

		SessionDetails details = sessionService.newSession(request, user);
		return ResultDTO.success(details);
	}

	@GetMapping("/logout")
	@ResponseBody
	public void logout(HttpServletRequest request, HttpServletResponse response) {
		// 退出本地登录
		sessionService.deleteSession(request);

		// 支持 oidc 登录
		if (oidcProps.isEnabled()) {
			try {
				request.getRequestDispatcher("/mamis/access/oidc/logout").forward(request, response);
				return;
			} catch (ServletException | IOException e) {
				log.error(e.getLocalizedMessage(), e);
			}
		}

		try {
			response.sendRedirect(StrUtil.isBlank(getContextPath(request)) ? "/" : getContextPath(request));
		} catch (IOException e) {
			log.error(e.getLocalizedMessage(), e);
		}

	}
}
